﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;

namespace daStaticAnalyser.Analysers
{
    using daStaticAnalyser;
    using daBase.Objects;
    using daBase.Analyser;
    using daSyntaxAnalyser;
    using daSyntaxAnalyser.SyntaxTree;

    /// <summary>
    /// Анализатор - метрики Джилба
    /// </summary>
    [AnalyserDefaultSettings("Метрики Джилба", "Метрика Джилба", 0, "Метрика Джилба - метрика сложности кода.")]
    public class GilbMetricAnalyzer : BaseStaticAnalyser
    {
        bool CLSet;

        [Category("Особые")]
        [DisplayName("Абсолютная трудность подпрограммы")]
        [Description("Если флаг не установлен, то метрика не выводиться.")]
        public bool IsCLSet { get { return CLSet; } set { CLSet = value; } }

        private int CalculateBranchOperators(ISyntaxTreeElement Element)
        {
            if (Element == null)
                return 0;
            int result = 0;
            if (Element is TestStatementElement) 
            {
                result = 1;
            }
            else if (Element is CaseStatementElement)
            {
                foreach (var Case in (Element as CaseStatementElement).Cases)
                {
                    if (Case is CaseElseStatementElement) { }
                    else result++;
                }
            }

            foreach (ISyntaxTreeElement element in Element)
                result += CalculateBranchOperators(element);
            return result;
        }
        
        protected override void DoAnalyse(SyntaxTreeArgs e)
        {
            String MethodName = "";
            if (CheckMethod_GetName(e, out MethodName))
            {
                int LSI = CalculateCountOperators((e.Element as OuterMethodElement).Body);
                int BranchOpCount = CalculateBranchOperators((e.Element as OuterMethodElement).Body);
                if (CLSet)
                {
                    AddMetric("Абсолютная трудность подпрограммы",
                            BranchOpCount,
                            MethodName,
                            e.Element.StartInfo.File,
                            e.Element.StartInfo.Line);
                }

                AddMetric("Относительная трудность подпрограммы",
                            ((float)BranchOpCount)/LSI,
                            MethodName,
                            e.Element.StartInfo.File,
                            e.Element.StartInfo.Line);
            }
        }
    }
}
